#ifndef MQTT_MANAGER_H
#define MQTT_MANAGER_H

#include <string>
#include <functional>
#include <memory>
#include <map>
#include <vector>
#include <mutex>
#include <atomic>

#include <esp_log.h>
#include <esp_timer.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

#include "esp_task_manager.h"
#include "esp_mqtt_impl.h"

struct ConnectionConfig {
    std::string broker_url;         ///< MQTT服务器URL (mqtt://host 或 mqtts://host)
    int port = 1883;                ///< 服务器端口号
    std::string client_id;          ///< 客户端唯一标识符
    std::string username;           ///< 用户名（可选）
    std::string password;           ///< 密码（可选）
    int keep_alive_seconds = 60;    ///< 保活时间（秒）
    bool clean_session = true;      ///< 是否清除会话
    int qos = 1;                    ///< 默认消息质量等级
    bool retain = false;            ///< 默认是否保留消息
    
    // 重连配置
    bool auto_reconnect = true;     ///< 是否自动重连
    int reconnect_interval_ms = 5000; ///< 重连间隔（毫秒）
    int max_reconnect_attempts = 10;  ///< 最大重连次数，0表示无限重试
    
    // 超时配置
    int connect_timeout_ms = 10000;    ///< 连接超时（毫秒）
    int message_timeout_ms = 5000;     ///< 消息发送超时（毫秒）
    
    // TLS配置（用于mqtts://）
    std::string ca_cert;            ///< CA证书内容
    std::string client_cert;        ///< 客户端证书内容
    std::string client_key;         ///< 客户端私钥内容
    bool skip_cert_verification = false; ///< 是否跳过证书验证（仅测试用）
};

typedef void (*mqtt_fast_callback_t)(const char* topic, const char* payload, size_t length, void* user_data);//c风格

using MqttCallback = std::function<void(const std::string& topic, const std::string& payload)>;//c++风格

// 高性能回调结构
struct RealtimeCallback {
    mqtt_fast_callback_t callback;
    void* user_data;
};

// 发布结果回调
using PublishCallback = std::function<void(bool success)>;

class MqttManager {
public:

    /**
     * @brief 获取单例实例
     * @return MqttManager& 管理器引用
     * @note 线程安全的延迟初始化
     */
    static MqttManager& GetInstance() {
        static MqttManager instance;
        return instance;
    }
    
    // 删除拷贝构造函数和赋值运算符
    MqttManager(const MqttManager&) = delete;
    MqttManager& operator=(const MqttManager&) = delete;

    bool start();

    // 订阅方法
    // 高性能通道 - 实时数据
    bool SubscribeRealtime(const char* topic, int qos, mqtt_fast_callback_t callback, void* user_data);
    
    // 标准通道
    bool Subscribe(const std::string& topic, int qos, MqttCallback callback);

    // 取消订阅方法
    bool Unsubscribe(const std::string& topic);
    bool UnsubscribeRealtime(const char* topic);

    // 发布方法
    /**
     * @brief 标准发布方法
     * @param topic 主题名
     * @param payload 负载数据
     * @param qos 消息质量等级 (0, 1, 2)
     * @param retain 是否保留消息
     * @return bool 发布是否成功
     */
    bool Publish(const std::string& topic, const std::string& payload, int qos = 0, bool retain = false);

    /**
     * @brief 异步发布方法（带回调）
     * @param topic 主题名
     * @param payload 负载数据
     * @param qos 消息质量等级 (0, 1, 2)
     * @param retain 是否保留消息
     * @param callback 发布完成回调
     * @return bool 发布是否成功启动
     */
    bool PublishAsync(const std::string& topic, const std::string& payload, int qos = 0, bool retain = false, PublishCallback callback = nullptr);

    /**
     * @brief 获取连接状态
     * @return bool 是否已连接
     */
    bool IsConnected() const;

private:
    // 私有构造函数和析构函数
    MqttManager();
    ~MqttManager();

    // 消息分发函数
    void OnMessageReceived(const std::string& topic, const std::string& payload);
    
    // 连接成功回调函数
    void OnConnected();

    std::unique_ptr<Mqtt> mqtt_;
    ConnectionConfig config_;

    std::shared_ptr<TaskExecutor> task_executor_;

    // 回调函数存储
    std::map<std::string, std::vector<RealtimeCallback>> realtime_callbacks_;  // 高性能回调
    std::map<std::string, std::vector<MqttCallback>> standard_callbacks_;     // 标准回调
    
    // 订阅信息跟踪（用于重连时重新订阅）
    std::map<std::string, int> subscribed_topics_;  // 主题名 -> QoS级别
    
    // 线程安全保护
    std::mutex callbacks_mutex_;
    
};

#endif // MQTT_MANAGER_H